再次回到角色區塊
我們在遊戲專案中,加入金錢元素
在 role.component.ts
加上 money
成員變數
...
export class RoleComponent implements OnInit {
name = '初心冒險者';
hp = 5;
atk = 1;
money = 0;
...
今天我想讓玩家自己能手動輸入自己擁有的錢
並修改 role.component.html
<h2>角色區塊</h2>
<div>名稱: {{name}}</div>
<div>血量: {{hp}}</div>
<div>攻擊力: {{atk}} <button (click)="addAtk()">點我增加攻擊力</button></div>
<div>金錢: {{money}} </div>
<input type="text" placeholder="自己的錢請自己輸入">
結果畫面
這個功能可以純粹透過前面章節的事件繫結來達成
這邊使用(input)
事件,當輸入框偵測到任何輸入都會觸發
同時要帶入$event
事件參數,$event
是詳細描述此次事件之各種數值的物件
有幾種
Evnet
方式可以玩看看
(input)
: 偵測任何輸入時觸發(keyup)
: 離開鍵盤按鍵時觸發(blur)
: 焦點(當前鼠標或鍵盤聚焦之處)離開輸入框時觸發(change)
: 焦點離開輸入框、並且值被改變時才觸發
修改 role.component.html
<h2>角色區塊</h2>
<div>名稱: {{name}}</div>
<div>血量: {{hp}}</div>
<div>攻擊力: {{atk}} <button (click)="addAtk()">點我增加攻擊力</button></div>
<div>金錢: {{money}} </div>
<input type="text" placeholder="自己的錢請自己輸入" (input)="changeMoney1($event)" >
在 role.component.ts
中增加 changeMoney1
、changeMoney2
方法
並且接收 event
事件參數
changeMoney1
可以換成 changeMoney2
試試看效果
修改 role.component.ts
...
export class RoleComponent implements OnInit {
...
changeMoney1(event: any) {
this.money = event.target.value;
}
changeMoney2(event: Event) {
let value = (event.target as HTMLInputElement).value;
this.money = Number(value);
}
}
changeMoney1
是用Javascript的作法取得輸入框的欄位值,因為是any
型別,Typescript不會對此做型別檢查changeMoney2
作法是將Event
事件,轉型成Typescript裡的物件類別HTMLInputElement
再做取值,最後轉型成數字完成畫面
不過,其實有更簡潔的方法可以達成這樣的功能
使用 [(ngModel)]="money"
也能得到相同效果
並且更加精簡,在ts程式碼完全不需要 changeMoney1
、changeMoney2
方法
<h2>角色區塊</h2>
<div>名稱: {{name}}</div>
<div>血量: {{hp}}</div>
<div>攻擊力: {{atk}} <button (click)="addAtk()">點我增加攻擊力</button></div>
<div>金錢: {{money}} </div>
<input type="text" placeholder="自己的錢請自己輸入" [(ngModel)]="money" >
若使用到ngModel
,要在Module模組底下 app.module.ts
新增 FormsModule
因為
ngModel
是隸屬於FormsModule
模組下的套件,所以要import進來為什麼
ngModel
隸屬在FormsModule
底下?
因為輸入值基本上是使用<input>
,而<input>
元素通常會是表單元件的一部份
[(ngModel)]="money"
同時帶了 屬性繫結[]
與 事件繫結()
兩種方式
短短的 [(ngModel)]="money"
其實代表著以下這行
[ngModel]="money" (ngModelChange)="money = $event">
[ngModel]="money"
是屬性繫結[]
,繫結對象綁定為money
(ngModelChange)="money = $event"
偵測到ngModel
值發生變化時,事件會被觸發
money = $event
$event
為ngModel的值
,是字串。而非前面的$event
是描述事件各項數值的物件
(ngModelChange)
是一個特殊的事件繫結
沿用了 AngularJS 的用法,他的存在一定伴隨著[ngModel]
事件觸發條件是當ngModel
值發生change
時才會觸發
所以才叫作ngModelChange
在前幾篇提的繫結,都是單向繫結
{{}}
把程式的值綁定到樣板,對元件而言是吐出值()
把樣板的值藉由事件傳遞給程式,對元件而言是接收值[]
把程式的值綁定到樣板,對元件而言是吐出值元件接收值:
view target
=>data source
元件吐出值:view target
<=data source
關於元件之間的
@Input
與@Output
用法,未來會再詳細介紹
雙向繫結意思是,對元件而言是接收值、也可以吐出值
因為雙向繫結同時包含 事件繫結 ()
、屬性繫結 []
所以寫法是用中括號包小括號[()]
表示,而中括號小括號的順序不能錯
有人說
[()]
像是banana in the box
香蕉躺在盒子裡
但個人覺得看起來更像是 鮑魚(食用貝類),並且鮑魚可以雙向進出
純粹記憶用途,千萬別把我黃標到這一步已經完成 77% 的Angular了